// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`A.js 1`] = `
/**
 * @flow
 */

var EventEmitter = require('events').EventEmitter;

// This pattern seems to cause the trouble.
var Bad = Object.assign({}, EventEmitter.prototype, {
  foo: function(): string { return 'hi'; }
});

// Calling Bad.foo() in the same file doesn't error
var bad: number = Bad.foo();

// Doesn't repro if I extend the class myself
class MyEventEmitter extends events$EventEmitter {}
var Good = Object.assign({}, MyEventEmitter.prototype, {
  foo: function(): string { return 'hi'; }
});
// Calling Good.foo() in the same file doesn't error
var good: number = Good.foo();

module.exports = {
  Bad: Bad,
  Good: Good,
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
 * @flow
 */

var EventEmitter = require("events").EventEmitter;

// This pattern seems to cause the trouble.
var Bad = Object.assign({}, EventEmitter.prototype, {
  foo: function(): string {
    return "hi";
  }
});

// Calling Bad.foo() in the same file doesn't error
var bad: number = Bad.foo();

// Doesn't repro if I extend the class myself
class MyEventEmitter extends events$EventEmitter {}
var Good = Object.assign({}, MyEventEmitter.prototype, {
  foo: function(): string {
    return "hi";
  }
});
// Calling Good.foo() in the same file doesn't error
var good: number = Good.foo();

module.exports = {
  Bad: Bad,
  Good: Good
};

`;

exports[`B.js 1`] = `
/**
 * @flow
 */

var A = require('./A.js');

var good: number = A.Good.foo();

var f = A.Bad.foo; // Property access is fine
var bad_: number = f(); // Calling the function is fine

var bad: number = A.Bad.foo(); // Method call is not fine
/*
B.js|12 col 1 error|  call of method foo
|| Property not found in
A.js|8 col 23 error|  object literal
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
 * @flow
 */

var A = require("./A.js");

var good: number = A.Good.foo();

var f = A.Bad.foo; // Property access is fine
var bad_: number = f(); // Calling the function is fine

var bad: number = A.Bad.foo(); // Method call is not fine
/*
B.js|12 col 1 error|  call of method foo
|| Property not found in
A.js|8 col 23 error|  object literal
*/

`;

exports[`apply.js 1`] = `
// @flow

(Object.assign.apply(null, [{}, {a: 1}, {b: 'foo'}]): {a: number, b: string});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow

(Object.assign.apply(null, [{}, { a: 1 }, { b: "foo" }]): {
  a: number,
  b: string
});

`;

exports[`non_objects.js 1`] = `
/* @flow */

Object.assign("123", {a: "foo"});
Object.assign(123, {a: "foo"});
Object.assign({a: "foo"}, 123);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

Object.assign("123", { a: "foo" });
Object.assign(123, { a: "foo" });
Object.assign({ a: "foo" }, 123);

`;

exports[`spread.js 1`] = `
// @flow

declare var arrOfObjs: Array<{ foo: string }>;
declare var roArrOfObjs: $ReadOnlyArray<{foo: string}>;
declare var tup: [{foo: string}, {bar: number}];

(Object.assign({}, ...arrOfObjs): { foo: number}); // Error: string ~> number
(Object.assign({}, ...roArrOfObjs): { foo: number}); // Error: string ~> number
(Object.assign({}, ...tup): { foo: string, bar: boolean}); // Error: number ~> boolean

(Object.assign(
  {},
  ...[{a: 1}, {b: 'foo'}],
  ...[{c: true}],
): {a: number, b: true, c: boolean}); // Error: 'foo' => true
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow

declare var arrOfObjs: Array<{ foo: string }>;
declare var roArrOfObjs: $ReadOnlyArray<{ foo: string }>;
declare var tup: [{ foo: string }, { bar: number }];

(Object.assign({}, ...arrOfObjs): { foo: number }); // Error: string ~> number
(Object.assign({}, ...roArrOfObjs): { foo: number }); // Error: string ~> number
(Object.assign({}, ...tup): { foo: string, bar: boolean }); // Error: number ~> boolean

(Object.assign({}, ...[{ a: 1 }, { b: "foo" }], ...[{ c: true }]): {
  a: number,
  b: true,
  c: boolean
}); // Error: 'foo' => true

`;

exports[`undefined.js 1`] = `
/* @flow */

var React = require('react');

type DefaultProps = {
  foo: number,
}

type Props = {
  foo: number,
}

class MyReactThing extends React.Component {
  props: Props;
  static defaultProps: DefaultProps;
  getFoo(): number { return this.props.foo; }
}

<MyReactThing />; // works
<MyReactThing foo={undefined} />; // also works
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");

type DefaultProps = {
  foo: number
};

type Props = {
  foo: number
};

class MyReactThing extends React.Component {
  props: Props;
  static defaultProps: DefaultProps;
  getFoo(): number {
    return this.props.foo;
  }
}

<MyReactThing />; // works
<MyReactThing foo={undefined} />; // also works

`;
